package com.ck.web.manager.shiro;

import com.ck.web.common.util.EncodeDecodeUtils;
import com.ck.web.common.util.MD5Util;
import com.ck.web.dal.mapper.LoginMapper;
import com.ck.web.dal.model.UserInfoDo;
import com.ck.web.shiro.LoginException;
import com.ck.web.shiro.LoginExceptionEnum;
import com.ck.web.shiro.SaltByteSource;
import com.ck.web.shiro.UserPrincipal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 登录认证和授权
 * Created by ChengK on 2017/1/10 0010.
 */
@Slf4j
public class UserLoginRealm extends AuthorizingRealm {

    @Autowired
    private LoginMapper loginMapper;

    /**
     * 授权操作
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 身份验证操作
     * @param authenticationToken 用户提交的身份信息，如：用户名、密码
     * @return 返回Shiro的认证信息 AuthenticationInfo
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        log.debug("==========================进入SHIRO doGetAuthenticationInfo=================================");
        //token中存放用户登录信息
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //获得用户名与密码
        String username = token.getUsername();
        String password = MD5Util.getMD5(String.valueOf(token.getPassword()));

        if(StringUtils.isBlank(username) || StringUtils.isBlank(password)){
            throw new LoginException(LoginExceptionEnum.USERNAME_PASSWORD_IS_EMPTY.getCode(),LoginExceptionEnum.USERNAME_PASSWORD_IS_EMPTY.getDesc());
        }

        //TODO 获取用户信息 此处不用验证密码,密码验证过程由AuthenticationInfo完成
        UserInfoDo reqDo = new UserInfoDo();
        reqDo.setLoginNo(username);
        UserInfoDo userInfoDo = loginMapper.findUserByLoginNo(reqDo);

        if(userInfoDo == null){
            throw new UnknownAccountException("不存在该账号");
        }

        // Password组成：前16存储密码的salt，16以后存储密码
        byte[] salt = EncodeDecodeUtils.decodeHex(userInfoDo.getLoginPwd().substring(0, 16));
        //返回认证信息由父类AuthenticatingRealm进行认证
        return new SimpleAuthenticationInfo(
                new UserPrincipal(userInfoDo.getLoginNo(),userInfoDo.getUserName(),userInfoDo.getEMail(),userInfoDo.getTelephone()), //用户信息
                userInfoDo.getLoginPwd().substring(16),
                new SaltByteSource(salt),
                getName());
    }
}
